home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1999 March / EnigmA AMIGA RUN 35 (1999)(G.R. Edizioni)(IT)[!][issue 1999-03].iso / earcd / grafica / amhelios / hc_scan.cpp < prev    next >
C/C++ Source or Header  |  1999-01-01  |  5KB  |  197 lines

  1. ////////////////////////////////////////////////////////////
  2. //
  3. //  HC_SCAN.CPP - Hemicube Scan Conversion Class
  4. //
  5. //  Version:    1.03A
  6. //
  7. //  History:    94/08/23 - Version 1.00A release.
  8. //              94/12/16 - Version 1.01A release.
  9. //              95/02/05 - Version 1.02A release.
  10. //              95/07/21 - Version 1.02B release.
  11. //              96/02/14 - Version 1.02C release.
  12. //              96/04/01 - Version 1.03A release.
  13. //
  14. //  Compilers:  Microsoft Visual C/C++ Professional V1.5
  15. //              Borland C++ Version 4.5
  16. //
  17. //  Author:     Ian Ashdown, P.Eng.
  18. //              byHeart Software Limited
  19. //              620 Ballantree Road
  20. //              West Vancouver, B.C.
  21. //              Canada V7S 1W3
  22. //              Tel. (604) 922-6148
  23. //              Fax. (604) 987-7621
  24. //
  25. //  Copyright 1994-1996 byHeart Software Limited
  26. //
  27. //  The following source code has been derived from:
  28. //
  29. //    Ashdown, I. 1994. Radiosity: A Programmer's
  30. //    Perspective. New York, NY: John Wiley & Sons.
  31. //
  32. //  It may be freely copied, redistributed, and/or modified
  33. //  for personal use ONLY, as long as the copyright notice
  34. //  is included with all source code files.
  35. //
  36. ////////////////////////////////////////////////////////////
  37.  
  38. #include "hc_poly.h"
  39. #include "hc_scan.h"
  40.  
  41. HemiScan::HemiScan()    // Class constructor
  42. {
  43.   int row;      // Loop index
  44.   
  45.   status = TRUE;        // Initialize object status
  46.  
  47.   // Allocate edge list
  48.   if ((edge_list = new FormEdgeInfo[FF_ArrayRes]) != NULL)
  49.   {
  50.     // Allocate cell information buffer
  51.     if ((cell_buffer = new (FormCellInfo (*[FF_ArrayRes])))
  52.         != NULL)
  53.     {
  54.       for (row = 0; row < FF_ArrayRes; row++)
  55.       {
  56.         if ((cell_buffer[row] =
  57.             new FormCellInfo[FF_ArrayRes]) == NULL)
  58.         {
  59.           // Release partially allocated buffer
  60.           row--;
  61.           for ( ; row >= 0; row--)
  62.             delete [] cell_buffer[row];
  63.           delete [] cell_buffer;
  64.  
  65.           // Release edge list memory 
  66.           delete [] edge_list;
  67.  
  68.           status = FALSE;
  69.           break;
  70.         }
  71.       }
  72.     }
  73.   }
  74.   else
  75.   {
  76.     delete [] edge_list;        // Release edge list memory
  77.     status = FALSE;
  78.   }
  79. }
  80.  
  81. HemiScan::~HemiScan()   // Class destructor
  82. {
  83.   int row;      // Loop index
  84.   
  85.   delete [] edge_list;          // Release edge list memory
  86.  
  87.   // Delete cell information buffer
  88.   for (row = 0; row < FF_ArrayRes; row++)
  89.     delete [] cell_buffer[row];
  90.   delete [] cell_buffer;
  91. }
  92.  
  93. // Initialize cell information buffer
  94. void HemiScan::InitBuffer()
  95. {
  96.   int row, col;     // Loop indices
  97.  
  98.   for (row = 0; row < FF_ArrayRes; row++)
  99.     for (col = 0; col < FF_ArrayRes; col++)
  100.     {
  101.       cell_buffer[row][col].depth = FF_Infinity;
  102.       cell_buffer[row][col].id = FF_None;
  103.     }
  104. }
  105.  
  106. void HemiScan::DrawEdgeList()   // Draw edge list
  107. {
  108.   int x, y;             // Loop indices
  109.   int sx, ex;           // Scan line x-axis co-ordinates
  110.   double dz;            // Pseudodepth delta
  111.   double iz;            // Element pseudodepth
  112.   double x_dist;        // X-axis distance
  113.   FormEdgeInfo *pedge;  // Edge info pointer
  114.   FormScanInfo *pss;    // Scan line start info pointer
  115.   FormScanInfo *pse;    // Scan line end info pointer
  116.   FormScanInfo *psw;    // Swap scan line info pointer
  117.  
  118.   pedge = &(edge_list[ymin]);
  119.   for (y = ymin; y < ymax; y++)
  120.   {
  121.     // Get scan line info pointers
  122.     pss = &(pedge->isect[0]);
  123.     pse = &(pedge->isect[1]);
  124.  
  125.     if (pss->x > pse->x)
  126.     {
  127.       // Swap scan line info pointers
  128.       psw = pss; pss = pse; pse = psw;
  129.     }
  130.  
  131.     // Get scan line x-axis co-ordinates
  132.     sx = (int) pss->x;
  133.     ex = (int) pse->x;
  134.  
  135.     if (sx < ex)        // Ignore zero-length segments
  136.     {
  137.       // Determine scan line start info
  138.       iz = pss->z;
  139.  
  140.       // Determine inverse slopes
  141.       x_dist = pse->x - pss->x;
  142.  
  143.       dz = (pse->z - iz) / x_dist;
  144.  
  145.       // Enter scan line
  146.       for (x = sx; x < ex; x++)
  147.       {
  148.         // Check element visibility
  149.         if (iz < (double) cell_buffer[y][x].depth)
  150.         {
  151.           // Update Z-buffer
  152.           cell_buffer[y][x].depth = (float) iz;
  153.  
  154.           // Set polygon identifier
  155.           cell_buffer[y][x].id = poly_id;
  156.         }
  157.  
  158.         // Update element pseudodepth
  159.         iz += dz;
  160.       }
  161.     }
  162.     pedge++;    // Point to next edge list element
  163.   }
  164. }
  165.  
  166. // Sum delta form factors
  167. void HemiScan::SumDeltas( float *ff_array, int face_id )
  168. {
  169.   WORD poly_id;     // Polygon identifier
  170.   int row, col;     // Face cell indices
  171.  
  172.   if (face_id == HC_TopFace)
  173.   {
  174.     // Scan entire face buffer
  175.     for (row = 0; row < FF_ArrayRes; row++)
  176.       for (col = 0; col < FF_ArrayRes; col++)
  177.       {
  178.         if ((poly_id = cell_buffer[row][col].id) !=
  179.             FF_None)
  180.           ff_array[poly_id - 1] +=
  181.               dff.GetTopFactor(row, col);
  182.       }
  183.   }
  184.   else
  185.   {
  186.     // Scan upper half of face buffer only
  187.     for (row = HC_ArrayDim; row < FF_ArrayRes; row++)
  188.       for (col = 0; col < FF_ArrayRes; col++)
  189.       {
  190.         if ((poly_id = cell_buffer[row][col].id) != FF_None)
  191.           ff_array[poly_id - 1] +=
  192.               dff.GetSideFactor(row, col);
  193.       }
  194.   }
  195. }
  196.  
  197.